﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Net;
using System.Reactive.Linq;
using System.Threading.Tasks;
using System.Windows.Input;
using Avalonia.Controls;
using Avalonia.Exusiai.Editor.Models;
using Avalonia.Exusiai.Editor.Views;
using MsBox.Avalonia;
using MsBox.Avalonia.Dto;
using MsBox.Avalonia.Enums;
using MsBox.Avalonia.Models;
using ReactiveUI;

namespace Avalonia.Exusiai.Editor.ViewModels;

public class ProjectFileViewModel : ViewModelBase
{
    //这个类承载了太多，暂时没时间，后续会被重构
    public ProjectFileViewModel()
    {
        _fileTree=new ObservableCollection<Node>();
        SelectedItem=new ObservableCollection<Node>();
        FileTree = new ObservableCollection<Node>();
        NewFolderCommand = ReactiveCommand.Create<Node>(NewFolder);
        NewFileCommand = ReactiveCommand.Create<Node>(NewFile);
        DeleteCommand = ReactiveCommand.Create<Node>(DeleteFile);
        CopyNameCommand =ReactiveCommand.Create<Node>(node=>App.CopyText(node.Name));
        CopyPathCommand =ReactiveCommand.Create<Node>(node=>App.CopyText(node.Path));
        RenameCommand = ReactiveCommand.Create<Node>(Rename);
        ShowInExplorerCommand = ReactiveCommand.Create<Node>(node=>App.ShowInExplorer(node.Path));
        UseDefaultEditorCommand = ReactiveCommand.Create<Node>(node=>App.UseDefaultEditor(node.Path));
        _selectFolderInteraction = new Interaction<string?, string[]?>();
        OpenFolderCommand = ReactiveCommand.Create(SelectFolder);
        OpenSelectedFolderCommand = ReactiveCommand.Create<Node>(OpenSelectedFolder);
        OpenSelectedFolderCommand2 = ReactiveCommand.Create(OpenSelectedFolder);
    }

    private void SearchFolder()
    {
        FileTree.Clear();
        GC.Collect();
        if(GlobalData.Instance.SelectedFolder!=null)
            Node.PopulateTree(GlobalData.Instance.SelectedFolder, FileTree);
        OpenSelectedFolder(FileTree[0]);
    }
    private async void Rename(Node selectedItem)
    {
        if (selectedItem == null) return;
        var messageBoxCustomParams = new MessageBoxCustomParams()
        {
            Icon = Icon.Info,
            ButtonDefinitions = new List<ButtonDefinition>()
            {
              new ButtonDefinition{Name = "OK",IsCancel = false},
              new ButtonDefinition{Name = "Cancel",IsCancel = true,IsDefault = true}
            },
            ContentTitle = "Rename",
            ContentMessage = $"\"{selectedItem.Name}\" will be rename,please input new name",
            WindowStartupLocation = WindowStartupLocation.CenterScreen,
            Topmost = true,
            InputParams = new InputParams()
            {
                DefaultValue = selectedItem.Name,
                Label = "New Name",
                Multiline = false,
            },
        };
        var messageBoxCustom= MessageBoxManager.GetMessageBoxCustom(messageBoxCustomParams);
        var result = await messageBoxCustom.ShowAsync();
        if (result != "OK")
            return;

        string newPath = Path.Combine(Path.GetDirectoryName(selectedItem.Path) ?? string.Empty, messageBoxCustom.InputValue);

        try
        {
            if (selectedItem.IsFile)
            {
                File.Move(selectedItem.Path, newPath);
            }
            else
            {
                Directory.Move(selectedItem.Path, newPath);
            }

            Node.RenameNode(selectedItem, messageBoxCustom.InputValue);
        }
        catch (IOException ex)
        {
            var messageBoxStandardParams = new MessageBoxStandardParams()
            {
                Icon = Icon.Warning,
                ButtonDefinitions = ButtonEnum.Ok,
                ContentTitle = "Rename",
                ContentMessage = $"\"{messageBoxCustom.InputValue}\" already exists: {ex.Message}",
                WindowStartupLocation = WindowStartupLocation.CenterScreen,
                Topmost = true
            };
            _ = MessageBoxManager.GetMessageBoxStandard(messageBoxStandardParams).ShowAsync();
        }
    }

    private async void DeleteFile(Node selectedItem)
    {
        var messageBoxStandardParams = new MessageBoxStandardParams()
        {
            Icon = Icon.Warning,
            ButtonDefinitions = ButtonEnum.OkCancel,
            ContentTitle = "Delete File",
            ContentMessage = $"\"{selectedItem.Name}\" will be deleted. Are you sure?",
            WindowStartupLocation = WindowStartupLocation.CenterScreen,
            Topmost = true
        };
        var result = await MessageBoxManager.GetMessageBoxStandard(messageBoxStandardParams).ShowAsync();
        if (result == ButtonResult.Ok)
        {
                Node.RemoveNodeRecursively(_fileTree, selectedItem);
                if (selectedItem.IsFile)
                    File.Delete(selectedItem.Path);
                else
                {
                    Directory.Delete(selectedItem.Path, true);
                }
        }
    }

    private static void NewFolder(Node selectedItem)
    {
        Node.NewFolder(selectedItem);
    }
    private static void NewFile(Node selectedItem)
    {
        Node.NewFile(selectedItem);
    }

    #region Commands
    private ObservableCollection<Node>? _fileTree;
    public ObservableCollection<Node> SelectedItem { get; set; }
    public ICommand DeleteCommand { get; }
    public ICommand CopyNameCommand { get; }
    public ICommand CopyPathCommand { get; }
    public ICommand RenameCommand { get; }
    public ICommand ShowInExplorerCommand { get; }
    public ICommand UseDefaultEditorCommand { get; }
    public ICommand NewFolderCommand { get; }
    public ICommand NewFileCommand { get; }
    #endregion
    #region OpenFolderCommand
    public ICommand OpenFolderCommand { get; }
    private string[]? _selectedFolder;
    private readonly Interaction<string?, string[]?> _selectFolderInteraction;
    public Interaction<string?, string[]?> SelectFolderInteraction => _selectFolderInteraction;

    private string[]? SelectedFolder
    {
        get => _selectedFolder;
        set => this.RaiseAndSetIfChanged(ref _selectedFolder, value);
    }
    public ObservableCollection<Node>? FileTree
    {
        get => _fileTree;
        set => this.RaiseAndSetIfChanged(ref _fileTree, value);
    }
    private async Task SelectFolder()
    {
        SelectedFolder = await _selectFolderInteraction.Handle("选择文件夹");
        GlobalData.Instance.SelectedFolder = WebUtility.UrlDecode(string.Join(", ", SelectedFolder ?? []));
        SearchFolder();
    }
    #endregion

    #region FileListView

    public ICommand OpenSelectedFolderCommand { get; }
    public ICommand OpenSelectedFolderCommand2 { get; }
    public ObservableCollection<FileListViewModel> FileList { get; } = [];
    public bool IsBusy { get; set; }
    public FileListViewModel? SelectedFile { get; set; }

    private void OpenSelectedFolder()
    {
        if (SelectedFile==null) return;
        OpenSelectedFolder(SelectedFile.Node);
    }
    private async void OpenSelectedFolder(Node selectedItem)
    {
        if(selectedItem.IsFile) {App.UseDefaultEditor(selectedItem.Path);return;}
        IsBusy = true;
        selectedItem.LoadChildren();
        FileList.Clear();
        await Task.Run(() =>
        {
            if (selectedItem.Children == null)
            {
                return;
            }
            foreach (var children in selectedItem.Children)
            {
                FileList.Add(new FileListViewModel(children));
            }
        });
    }

    #endregion
}